<script lang="ts" setup>
import DefaultTheme from 'vitepress/theme'
import ScrollToTop from './components/scroll-to-top.vue'
import { useData } from 'vitepress'
import { nextTick, provide } from 'vue'
import { useImageZoom } from './hooks/zoom'
import { useOutlineAutoScroll } from './hooks/outline'
import { useSidebarActiveIntoView } from './hooks/sidebar'

const { isDark } = useData()

const enableTransitions = () =>
  'startViewTransition' in document &&
  window.matchMedia('(prefers-reduced-motion: no-preference)').matches

provide(
  'toggle-appearance',
  async ({ clientX: x, clientY: y }: MouseEvent) => {
    if (!enableTransitions()) {
      isDark.value = !isDark.value
      return
    }

    const clipPath = [
      `circle(0px at ${x}px ${y}px)`,
      `circle(${Math.hypot(
        Math.max(x, innerWidth - x),
        Math.max(y, innerHeight - y),
      )}px at ${x}px ${y}px)`,
    ]

    await document.startViewTransition(async () => {
      isDark.value = !isDark.value
      await nextTick()
    }).ready

    document.documentElement.animate(
      { clipPath: isDark.value ? clipPath.reverse() : clipPath },
      {
        duration: 300,
        easing: 'ease-in',
        pseudoElement: `::view-transition-${
          isDark.value ? 'old' : 'new'
        }(root)`,
      },
    )
  },
)

useImageZoom()

useOutlineAutoScroll()

useSidebarActiveIntoView()
</script>

<template>
  <DefaultTheme.Layout>
    <template #layout-bottom>
      <ScrollToTop />
    </template>
  </DefaultTheme.Layout>
</template>

<style>
::view-transition-old(root),
::view-transition-new(root) {
  animation: none;
  mix-blend-mode: normal;
}

::view-transition-old(root),
.dark::view-transition-new(root) {
  z-index: 1;
}

::view-transition-new(root),
.dark::view-transition-old(root) {
  z-index: 9999;
}

.VPSwitchAppearance {
  width: 22px !important;
}

.VPSwitchAppearance .check {
  transform: none !important;
}
</style>
